package mock

import (
	"math"
	"math/rand"
	"sync"
	"time"

	"gitee.com/rw555/fdsmastergo/pkg/device"
	"gitee.com/rw555/fdsmastergo/pkg/keypad"
	"gitee.com/rw555/fdsmastergo/pkg/logger"
	"go.uber.org/zap"
)

type MockDevice struct {
	mu            sync.RWMutex
	currentTemp   float64
	isAscending   bool
	lastUpdate    time.Time
	initialized   bool
	ratePerSecond float64
	pumpDuty      int
	isPumpOpen    bool
	isHeater1Open bool
	isHeater2Open bool
	keyStates     map[keypad.Key]keypad.KeyState
}

func NewMockDevice() device.Device {
	return &MockDevice{
		currentTemp:   200.0,
		isAscending:   true,
		lastUpdate:    time.Now(),
		initialized:   false,
		ratePerSecond: 1.0,
		pumpDuty:      80,
		isPumpOpen:    false,
		isHeater1Open: false,
		isHeater2Open: false,
		keyStates:     make(map[keypad.Key]keypad.KeyState),
	}
}

func (d *MockDevice) OpenPump() error {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.isPumpOpen = true
	logger.OperationInfo("开泵")
	return nil
}

func (d *MockDevice) ClosePump() error {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.isPumpOpen = false
	logger.OperationInfo("关泵")
	return nil
}

func (d *MockDevice) PumpIsRunning() (bool, error) {
	d.mu.RLock()
	defer d.mu.RUnlock()
	return d.isPumpOpen, nil
}

func (d *MockDevice) SetPumpPower(duty int) error {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.pumpDuty = duty
	return nil
}

func (d *MockDevice) GetPumpPower() (int, error) {
	d.mu.Lock()
	defer d.mu.Unlock()
	return d.pumpDuty, nil
}

func (d *MockDevice) OpenHeater1() error {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.isHeater1Open = true
	logger.OperationInfo("开加热1")
	return nil
}

func (d *MockDevice) CloseHeater1() error {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.isHeater1Open = false
	logger.OperationInfo("关加热1")
	return nil
}

func (d *MockDevice) IsHeater1Open() (bool, error) {
	d.mu.RLock()
	defer d.mu.RUnlock()
	return d.isHeater1Open, nil
}

func (d *MockDevice) OpenHeater2() error {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.isHeater2Open = true
	logger.OperationInfo("开加热2")
	return nil
}

func (d *MockDevice) CloseHeater2() error {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.isHeater2Open = false
	logger.OperationInfo("关加热2")
	return nil
}

func (d *MockDevice) IsHeater2Open() (bool, error) {
	d.mu.RLock()
	defer d.mu.RUnlock()
	return d.isHeater2Open, nil
}

func (d *MockDevice) GetTemp() int {
	d.mu.Lock()
	defer d.mu.Unlock()

	now := time.Now()
	if !d.initialized {
		d.initialized = true
		d.lastUpdate = now
		return int(math.Round(d.currentTemp))
	}

	elapsed := now.Sub(d.lastUpdate)

	// 根据当前温度和方向决定变化速率
	switch {
	case d.isAscending:
		switch {
		case d.currentTemp >= 280:
			d.ratePerSecond = 1.0
		case d.currentTemp >= 260:
			d.ratePerSecond = 1.0 / 6.0
		case d.currentTemp >= 250:
			d.ratePerSecond = 1.0 / 4.0
		default:
			d.ratePerSecond = 1.0
		}

		// 达到300度时开始下降
		if d.currentTemp >= 300 {
			d.isAscending = false
		}
	case !d.isAscending:
		switch {
		case d.currentTemp <= 220:
			d.ratePerSecond = -1.0
		case d.currentTemp <= 240:
			d.ratePerSecond = -1.0 / 6.0
		case d.currentTemp <= 250:
			d.ratePerSecond = -1.0 / 4.0
		default:
			d.ratePerSecond = -1.0
		}

		// 达到200度时开始上升
		if d.currentTemp <= 200 {
			d.isAscending = true
		}
	}

	// 计算温度变化
	delta := d.ratePerSecond * elapsed.Seconds()
	d.currentTemp += delta
	d.lastUpdate = now

	return int(math.Round(d.currentTemp))
}

func (d *MockDevice) GetKeyState(key keypad.Key) (keypad.KeyState, error) {
	d.mu.RLock()
	defer d.mu.RUnlock()
	if state, exists := d.keyStates[key]; exists {
		return state, nil
	}
	return keypad.KeyReleased, nil
}

func (d *MockDevice) AsKeypad() keypad.Keypad {
	return d
}

// SimulateRandomKeyPress 启动随机按键模拟
func (d *MockDevice) SimulateRandomKeyPress(quit chan struct{}) {
	go func() {
		time.Sleep(3 * time.Second)
		// 先模拟一次菜单键短按，启动自动模式
		d.SimulateKeyPress(keypad.KeyMenu)
		time.Sleep(500 * time.Millisecond)
		d.SimulateKeyRelease(keypad.KeyMenu)

		// 等待10秒后关闭自动模式
		time.Sleep(10 * time.Second)
		d.SimulateKeyPress(keypad.KeyMenu)
		time.Sleep(500 * time.Millisecond)
		d.SimulateKeyRelease(keypad.KeyMenu)

		// 启动随机按键模拟定时器
		ticker := time.NewTicker(8 * time.Second)
		defer ticker.Stop()

		keys := []keypad.Key{
			keypad.KeyMenu,
			keypad.KeyF1,
			keypad.KeyF2,
			keypad.KeyF3,
		}

		pressTypes := []struct {
			name     string
			duration time.Duration
		}{
			{"短按", 500 * time.Millisecond},
			{"长按", 4 * time.Second},
			{"超长按", 7 * time.Second},
		}

		for {
			select {
			case <-ticker.C:
				// 随机选择按键和按压类型
				key := keys[rand.Intn(len(keys))]
				pressType := pressTypes[rand.Intn(len(pressTypes))]

				//logger.OperatorInfo("模拟按键",
				//	zap.String("key", key.String()),
				//	zap.String("type", pressType.name))

				// 模拟按下
				d.SimulateKeyPress(key)

				// 等待指定时长
				time.Sleep(pressType.duration)

				// 模拟释放
				d.SimulateKeyRelease(key)

				logger.OperationInfo("模拟按键",
					zap.String("key", key.String()),
					zap.String("type", pressType.name))

			case <-quit:
				return
			}
		}
	}()
}

// SimulateKeyPress 模拟按键按下
func (d *MockDevice) SimulateKeyPress(key keypad.Key) {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.keyStates[key] = keypad.KeyPressed
}

// SimulateKeyRelease 模拟按键释放
func (d *MockDevice) SimulateKeyRelease(key keypad.Key) {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.keyStates[key] = keypad.KeyReleased
}
